from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.events import EventFiringWebDriver, AbstractEventListener
import time
import re

#URL="https://www.jd.com/?a=1711300212603"
URL="https://www.jd.com"

# a dictionary list, with the pattern ('shelf':'A-Z','serial_number':'000-999')
CODELIST=[]

class myOrder:
    def __init__(self,name,shop,element_to_click):
        self.name=name
        self.shop=shop
        self.element_to_click=element_to_click
    
#    def SelectJD(self):
#        if self.name=="京东" 

class MyListener(AbstractEventListener):
    def after_click(self,element,url): ## warning ##  # i do not know why i append the exact arg 'url', but it works (after doing this the TypeError disappeared
        print(f"onClick element: {element}")

    def on_find(self,element):
        print(f"Find element: {element}")

def init_chrome():
    #create a WebDriver object
    driver=webdriver.Chrome()

    driver.get(URL)
    assert "京东" in driver.title  # for mainland Chinese users only
    return driver

def init_EF_chrome():
    driver=webdriver.Chrome()
    ef_driver=EventFiringWebDriver(driver,MyListener())
    ef_driver.get(URL)
    element_to_click=ef_driver.find_element(By.PARTIAL_LINK_TEXT,"请登录")
    element_to_click.click()
    QRcode_to_click=ef_driver.find_element(By.CLASS_NAME,"login-tab-l")
    QRcode_to_click.click()
    time.sleep(120)

#def login(deliver):
#    deliver

def LoginEnsure(object):
    try:
        loginLink=object.find_element(By.PARTIAL_LINK_TEXT,"请登录")
        loginLink.click()
        #assert "登录"  in object.title
        print(object.title)

        #showLoginScan=object.find_element(By.CLASS_NAME)
        loginByScan_click=object.find_element(By.CLASS_NAME,"login-tab-l")
        loginByScan_click.click()

        # explicit waits used to listen if login successfully
        WebDriverWait(object,600).until(
            #EC.url_changes # wrong judgement condition
            EC.url_matches("https://www.jd.com")
        )

        #actions=ActionChains(object)
        #actions.click(loginByScan)
        #time.sleep(20) # add event react: login successfully 
        #assert "登录"  in object.title
        #loginByScan.click()
        #return
    finally:
        return object


def GainCode(o,i):

    element = o.find_element(By.XPATH, "//*[contains(concat(' ', normalize-space(@class), ' '), ' show-phone ')]")
    text = element.text
    print(text)
    pattern=r"取件码 (\w+)-(\d+)"
    match=re.search(pattern,text)
    if match:
        shelf=match.group(1)   # the first ():(\w+) is the group(1)
        serial_number=match.group(2)
        CODELIST.append({'shelf':shelf,'serial_number':serial_number,'good(s)':""})
        print(CODELIST[i])
    else:
        print("No match found")

    return

def OpenNewTag(o,l,i):
    l.click()
    time.sleep(2)
    windows=o.window_handles
    print(windows)
    o.switch_to.window(windows[2])
    print(o.title)
    time.sleep(3)

    GainCode(o,i)
    driver.close()
    o.switch_to.window(windows[1])
    return

def GetGoodOrder(object):
    elem_OrderLINK=object.find_element(By.LINK_TEXT,"我的订单")
    elem_OrderLINK.click()
    #assert "我的订单" in object.title
    #需要切换窗口

    windows=object.window_handles
    print(windows)
    object.switch_to.window(windows[1])
    print(object.title)

    wait_for_dlivery=object.find_element(By.PARTIAL_LINK_TEXT,"待收货/使用")
    wait_for_dlivery.click()

    table = WebDriverWait(object, 10).until(EC.presence_of_element_located((By.TAG_NAME, "table")))
    #rows = table.find_element(By.TAG_NAME, "table").find_elements(By.TAG_NAME,"tbody")
    #status=table.find_elements(By.XPATH,("//*[contains(concat(' ', normalize-space(@class), ' '), ' status ')]"))
    #parent_elements = driver.find_elements(By.XPATH, "//span[contains(concat(' ', normalize-space(@class), ' '), ' ftx-02 ')]/..")
    #status_elements = object.find_elements(By.XPATH, "//div[contains(concat(' ', normalize-space(@class), ' '), ' status ')]//span[contains(concat(' ', normalize-space(@class), ' '), ' ftx-02 ')]/..")
    time.sleep(5)
    elements = driver.find_elements(By.XPATH, "//*[contains(@id, 'tb-')]")
    i=0
    # 遍历找到的元素并打印它们的ID
    for element in elements:
        time.sleep(3)
        print(element.get_attribute('id'))
        status=element.text
        #print(status)
        #pattern_goods=r"京东(\w+)请上门自提"
        #match=re.search(pattern_goods,status)
        #if match:
         #   goodsInfo=match.group(1)
        #else:
        #    print("no match goodsInfo")
        #    print(goodsInfo)
        if "上门自提" in status:
            link=element.find_element(By.TAG_NAME,"a")
            OpenNewTag(object,link,i)
            #CODELIST[i]['good(s)']=goodsInfo
            i+=1

def display_dict_list(dict_list):
    output = ""
    for item in dict_list:
        output += f"{item['shelf']}-{item['serial_number']}\n"
    print(output)


def SortGoods(list):
    sorted_CODELIST = sorted(list, key=lambda x: (x['shelf'], x['serial_number']))
    display_dict_list(sorted_CODELIST)

if __name__ == '__main__':
    #elem_OrderForGoods=driver.find_element(By.CLASS_NAME,"dt")
    #driver=webdriver.Chrome()
    driver=init_chrome()
    
    LoginEnsure(driver)
    time.sleep(5)
    
    GetGoodOrder(driver)

    print(CODELIST)
    SortGoods(CODELIST)
    #elem_OrderForGoods=driver.find_element(By.LINK_TEXT,"我的订单")
    #print(elem_OrderForGoods))
    #init_EF_chrome()
